/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.ec.tmall.web.TmallAction
   Module Description   :

   Date Created      : 2011/11/17
   Original Author   : cut7man
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.ec.tmall.web;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import javax.annotation.Resource;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.springframework.beans.factory.annotation.Autowired;

import com.taobao.api.domain.Item;
import com.taobao.api.domain.PropValue;
import com.taobao.api.domain.Sku;
import com.yaodian100.core.admin.utils.AdminHelper;
import com.yaodian100.core.batch.service.BatchJobService;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.utils.JspUtil;
import com.yaodian100.core.menu.entity.Option;
import com.yaodian100.core.menu.service.MenuService;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.order.entity.InterceptOrder;
import com.yaodian100.ec.order.entity.OrderProduct;
import com.yaodian100.ec.order.entity.OrderProductDetail;
import com.yaodian100.ec.order.entity.Orders;
import com.yaodian100.ec.order.service.InterceptOrderService;
import com.yaodian100.ec.order.service.OrderService;
import com.yaodian100.ec.product.entity.Specification;
import com.yaodian100.ec.tmall.service.TmallService;

/**
 * @author cut7man
 * 
 */
public class TmallAction {

	@Autowired
	private TmallService tmallService;
	@Autowired
	private OrderService orderService;
	@Resource
	private BatchJobService batchJobService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private MenuService menuService;
	@Autowired
	private InterceptOrderService interceptOrderService;

	private String tid;
	private String memo;
	private String state;
	private String result;
	private String orderTid;

	public String addInterceptOrder() {
		Member member = memberService.get(menuService.get

		("SystemValue").getOptions().get("tmall_member").getMemo1());
		Map<String, String> values = new HashMap<String, String>();
		values.put("memo", memo);
		result = interceptOrderService.createInterceptOrder

		("interceptOrder", values, AdminHelper.getUser().getUsername(), member.getDomainSrc(), state, tid);
		return "toInterceptOrder";
	}

	public String edit() {
		Member member = memberService.get(menuService.get

		("SystemValue").getOptions().get("tmall_member").getMemo1());
		if (orderTid == null) {
			return "editInterceptOrder";
		} else {
			if ("".equals(orderTid)) {
				if (tid != null && !"".equals(tid)) {
					Map<String, String> values = new

					HashMap<String, String>();
					values.put("memo", memo);
					interceptOrderService.editOrder

					("interceptOrder", tid, state, member.getDomainSrc(), AdminHelper.getUser().getUsername(), values);
					Map<String, Object> map =

					interceptOrderService.findOrder(tid, member.getDomainSrc());
					InterceptOrder interceptOrder =

					(InterceptOrder) map.get("interceptOrder");
					tid = interceptOrder.getOuterOderId();
					memo = map.get("memo").toString();
					state = interceptOrder.getState();
					return "editInterceptOrder";
				}
			}
			Map<String, Object> map =

			interceptOrderService.findOrder(orderTid, member.getDomainSrc());
			if (map.size() > 0) {

				InterceptOrder interceptOrder = (InterceptOrder)

				map.get("interceptOrder");
				tid = interceptOrder.getOuterOderId();
				memo = map.get("memo").toString();
				state = interceptOrder.getState();
			} else {
				result = "error";
			}
		}
		return "editInterceptOrder";
	}

	public String toAddInterceptOrder() {
		return "toInterceptOrder";
	}

	public String confirmUpdateOrder() {
		// 订单改完直接配送
		Orders order = (Orders) baseMgr.get(Orders.class, orderId);
		if (order.getOrderSt().equals("05")) {
			order.setOrderSt("20");
			baseMgr.update(order);
		}
		this.order = order;
		message = "订单已确认配送！";
		return "updateOrder";
	}

	public String updateOrder() {
		this.order = tmallService.updateTmallOrder(orderId, presentQty, specProp);
		return "updateOrder";
	}

	public String toUpdateOrder() {
		Option option = JspUtil.menuOption("SystemValue", "tmall_present");
		String[] specIds = {};
		if (option.getMemo1() != null && option.getMemo1().length() > 0) {
			specIds = option.getMemo1().split(",");
		}
		maxPresentQty = option.getMemo2();
		if (specIds != null && specIds.length > 0) {
			for (String specId : specIds) {
				Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(specId));
				presentSpecs.add(spec);
			}
		}

		Orders order = (Orders) baseMgr.get(Orders.class, orderId);
		for (int i = 0; i < order.getOrderProduct().size(); i++) {
			OrderProduct op = order.getOrderProduct().get(i);
			List<OrderProductDetail> opds = op.getOrderProductDetail();
			for (OrderProductDetail opd : opds) {
				boolean isNeedSkip = false;
				if (tmallProducts != null && tmallProducts.size() > 0 && opd.getOuterProdId() != null
						&& opd.getOuterProdId().length() > 0) {
					for (Item item : tmallProducts) {
						if (item.getNumIid().longValue() == Long.valueOf(opd.getOuterProdId()).longValue()) {
							isNeedSkip = true;
							break;
						}
					}
				}
				if (opd.getOuterProdId() == null || opd.getOuterProdId().length() == 0) {
					isNeedSkip = true;
				}
				if ((op.getProdTp().equals("0") || op.getProdTp().equals("6")) && !isNeedSkip) {
					Item item = tmallService.getItem(Long.valueOf(opd.getOuterProdId()));
					tmallProducts.add(item);
					for (Sku sku : item.getSkus()) {
						List<PropValue> thePvs = tmallService.getSkuProps(opd.getOuterCid(), sku.getProperties());
						pvs.put(sku.getSkuId(), thePvs);
					}

				}
			}
		}
		return "toUpdateOrder";
	}

	public String toUpdateSessionKey() {

		return "toUpdateSessionKey";
	}

	private String getMessageBody(String url) {
		String message = null;
		HttpClient client = new HttpClient();
		HttpMethod method = new GetMethod(url);

		try {
			int statusCode = client.executeMethod(method);

			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("Method failed: " + method.getStatusLine());
			}

			byte[] responseBody = method.getResponseBody();
			message = new String(responseBody);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			method.releaseConnection();

		}
		return message;
	}

	public String updateSessionKey() {
		String url = "http://container.open.taobao.com/container?authcode=";

		String messageBody = getMessageBody(url + authcode);
		String[] messageSplit = messageBody.split("&");
		Map<String, String> values = new HashMap<String, String>();
		for (int i = 0; i < messageSplit.length; i++) {
			String[] valueSplit = messageSplit[i].split("=");
			if (valueSplit.length > 1) {
				values.put(valueSplit[0], valueSplit[1]);
			}
		}
		Map<String, String> parameterValues = convertBase64StringtoMap(values.get("top_parameters"));
		String appkey = values.get("top_appkey");
		String refreshToken = parameterValues.get("refresh_token");
		String sessionKey = values.get("top_session");
		if (refreshToken == null || refreshToken.length() == 0) {
			refreshToken = sessionKey;
		}
		// String sign = values.get("top_sign");
		try {
			activateSessionKey(appkey, sessionKey, refreshToken);
			message = "完成更新";
		} catch (Exception e) {
			e.printStackTrace();
			message = "update sessionKey fail:" + e.getMessage();
		}

		return "toUpdateSessionKey";

	}

	/**
	 * 把经过BASE64编码的字符串转换为Map对象
	 * 
	 * @param str
	 * @return
	 * @throws Exception
	 */
	private static Map<String, String> convertBase64StringtoMap(String str) {
		if (str == null) {
			return null;
		}
		String keyvalues = null;
		try {
			keyvalues = new String(Base64.decodeBase64(URLDecoder.decode(str, "utf-8").getBytes("utf-8")));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		String[] keyvalueArray = keyvalues.split("\\&");
		Map<String, String> map = new HashMap<String, String>();
		for (String keyvalue : keyvalueArray) {
			String[] s = keyvalue.split("\\=");
			if (s == null || s.length != 2) {
				return null;
			}
			map.put(s[0], s[1]);
		}
		return map;
	}

	private void activateSessionKey(String appkey, String sessionKey, String refreshToken) throws Exception {
		Option op = JspUtil.menuOption("SystemValue", "tmall_appKey");
		String secret = op.getMemo2();
		Map<String, String> signParams = new TreeMap<String, String>();
		signParams.put("appkey", appkey);
		signParams.put("refresh_token", refreshToken);
		signParams.put("sessionkey", sessionKey);
		StringBuilder paramsString = new StringBuilder();
		Set<Entry<String, String>> paramsEntry = signParams.entrySet();
		for (Entry paramEntry : paramsEntry) {
			paramsString.append(paramEntry.getKey()).append(paramEntry.getValue());
		}

		String sign = DigestUtils.md5Hex((paramsString.toString() + secret).getBytes("utf-8")).toUpperCase();
		sign = URLEncoder.encode(sign, "utf-8");
		appkey = URLEncoder.encode(appkey, "utf-8");
		refreshToken = URLEncoder.encode(refreshToken, "utf-8");
		sessionKey = URLEncoder.encode(sessionKey, "utf-8");

		String url = "http://container.open.taobao.com/container/refresh?appkey=" + appkey + "&refresh_token="
				+ refreshToken + "&sessionkey=" + sessionKey + "&sign=" + sign;
		String message = getMessageBody(url);

		Option tmallSessionKey = JspUtil.menuOption("SystemValue", "tmall_sessionKey");
		tmallSessionKey.setMemo1(sessionKey);
		Calendar now = Calendar.getInstance();
		now.add(Calendar.YEAR, 1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		tmallSessionKey.setMemo2(sdf.format(now.getTime()));
		// JOB insert
		batchJobService
				.save("SyncTmallSessionKey", "<root><sessionKey>" + sessionKey + "</sessionKey><dueDay>" + now.getTime()
						+ "</dueDay></root>", null, "tmall");

	}

	private String authcode;
	private String message;
	@Autowired
	private BaseManager baseMgr;

	/**
	 * @return the authcode
	 */
	public String getAuthcode() {
		return authcode;
	}

	/**
	 * @param authcode the authcode to set
	 */
	public void setAuthcode(String authcode) {
		this.authcode = authcode;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	public static void main(String args[]) {
		// String message =
		// "top_appkey=12380686&top_parameters=aWZyYW1lPTAmdHM9MTMyMTUxNjQyNjMxMCZ2aXNpdG9yX2lkPTc2MjM1OTg0NiZ2aXNpdG9yX25pY2s90qu14zEwMLnZt73G7L2iteo=&top_session=411170554bb3qJOvRcQs18bd9c5d2d667d166f8bed36b2d7623598461&top_sign=z/p6ohZkxr3nvHHSHRuJ4A==";
		String authcode = "TOP-102df2e5550474636d588ccdd258fba5earltiHvJz93HidZw6r0ACUCjPwXZi0d-END";
		TmallAction ta = new TmallAction();
		ta.setAuthcode(authcode);
		ta.updateSessionKey();
	}

	private String orderId;

	/**
	 * @return the tmallProduct
	 */
	public List<Item> getTmallProducts() {
		return tmallProducts;
	}

	/**
	 * @param tmallProduct the tmallProduct to set
	 */
	public void setTmallProducts(List<Item> tmallProduct) {
		this.tmallProducts = tmallProduct;
	}

	/**
	 * @return the orderId
	 */
	public String getOrderId() {
		return orderId;
	}

	/**
	 * @param orderId the orderId to set
	 */
	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}

	private List<Item> tmallProducts = new ArrayList<Item>();
	private Map<Long, List<PropValue>> pvs = new HashMap<Long, List<PropValue>>();
	private String[] specProp;

	/**
	 * @return the specProp
	 */
	public String[] getSpecProp() {
		return specProp;
	}

	/**
	 * @param specProp the specProp to set
	 */
	public void setSpecProp(String[] specProp) {
		this.specProp = specProp;
	}

	/**
	 * @return the pvs
	 */
	public Map<Long, List<PropValue>> getPvs() {
		return pvs;
	}

	/**
	 * @param pvs the pvs to set
	 */
	public void setPvs(Map<Long, List<PropValue>> pvs) {
		this.pvs = pvs;
	}

	private String maxPresentQty;

	/**
	 * @return the maxPresentQty
	 */
	public String getMaxPresentQty() {
		return maxPresentQty;
	}

	/**
	 * @param maxPresentQty the maxPresentQty to set
	 */
	public void setMaxPresentQty(String maxPresentQty) {
		this.maxPresentQty = maxPresentQty;
	}

	private List<Specification> presentSpecs = new ArrayList<Specification>();

	/**
	 * @return the presentSpecs
	 */
	public List<Specification> getPresentSpecs() {
		return presentSpecs;
	}

	/**
	 * @param presentSpecs the presentSpecs to set
	 */
	public void setPresentSpecs(List<Specification> presentSpecs) {
		this.presentSpecs = presentSpecs;
	}

	private String[] presentQty;

	/**
	 * @return the presentQty
	 */
	public String[] getPresentQty() {
		return presentQty;
	}

	/**
	 * @param presentQty the presentQty to set
	 */
	public void setPresentQty(String[] presentQty) {
		this.presentQty = presentQty;
	}

	private Orders order;

	/**
	 * @return the order
	 */
	public Orders getOrder() {
		return order;
	}

	/**
	 * @param order the order to set
	 */
	public void setOrder(Orders order) {
		this.order = order;
	}

	public String getTid() {
		return tid;
	}

	public void setTid(String tid) {
		this.tid = tid;
	}

	public String getMemo() {
		return memo;
	}

	public void setMemo(String memo) {
		this.memo = memo;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public String getOrderTid() {
		return orderTid;
	}

	public void setOrderTid(String orderTid) {
		this.orderTid = orderTid;
	}

}
